package org.gist.classloader.utils;

import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Hierarchy;
import org.apache.log4j.Level;
import org.apache.log4j.LogManager;
import org.apache.log4j.spi.LoggerRepository;
import org.apache.log4j.spi.RepositorySelector;
import org.apache.log4j.spi.RootLogger;
import org.apache.log4j.xml.DOMConfigurator;

/**
 * @author Suresh Reddy Guntaka
 * 
 */
public class GclRepositorySelector implements RepositorySelector {
    private static boolean initialized = false;
    private static Object guard = LogManager.getRootLogger();
    private static Map<ClassLoader, LoggerRepository> repositories = new HashMap<ClassLoader, LoggerRepository>();
    private static LoggerRepository defaultRepository;
    private static final String LOG4JXML = "log4j.xml";

    public static synchronized void init() {
        if( !initialized ) {
            defaultRepository = LogManager.getLoggerRepository();
            RepositorySelector theSelector = new GclRepositorySelector();
            LogManager.setRepositorySelector( theSelector, guard );
            initialized = true;
        }

        Hierarchy hierarchy = new Hierarchy( new RootLogger( Level.DEBUG ) );
        loadLog4JConfig( hierarchy );
        repositories.put( GclRepositorySelector.class.getClassLoader(), hierarchy );
    }

    public static synchronized void removeFromRepository() {
        repositories.remove( GclRepositorySelector.class.getClassLoader() );
    }

    private static void loadLog4JConfig(Hierarchy hierarchy) {
        InputStream log4JConfig = GclRepositorySelector.class.getClassLoader().getResourceAsStream( LOG4JXML );
        DOMConfigurator conf = new DOMConfigurator();
        conf.doConfigure( log4JConfig, hierarchy );
    }

    private GclRepositorySelector() {
    }

    public LoggerRepository getLoggerRepository() {
        LoggerRepository repository = repositories.get( GclRepositorySelector.class.getClassLoader() );
        if( repository == null ) {
            return defaultRepository;
        } else {
            return repository;
        }
    }
}